package com.cwd.arm.domain.repository.impl;

import com.baomidou.mybatisplus.core.toolkit.CollectionUtils;
import com.cwd.arm.common.enums.ErrorEnum;
import com.cwd.arm.common.exception.ArmException;
import com.cwd.arm.domain.entity.ReceiveNodeEntity;
import com.cwd.arm.domain.entity.ReceiveRecordEntity;
import com.cwd.arm.domain.repository.ProjectRepository;
import com.cwd.arm.domain.repository.ReceiveNodeRepository;
import com.cwd.arm.infrastructure.dao.ReceiveRecordDao;
import com.cwd.arm.infrastructure.dao.TaxDao;
import com.cwd.arm.infrastructure.po.ReceiveRecordPo;
import com.cwd.arm.infrastructure.po.TaxPo;
import com.cwd.arm.domain.entity.TaxEntity;
import com.cwd.arm.domain.repository.TaxRepository;
import com.cwd.arm.infrastructure.query.ReceiveRecordDaoQuery;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Repository;

import java.util.List;

/**
 * Description:开票信息
 * Created on 2021年11月16日
 *
 * @author yan
 */
@Repository
public class TaxRepositoryImpl implements TaxRepository {

    @Autowired
    private TaxDao dao;

    @Autowired
    private ReceiveRecordDao receiveRecordDao;

    @Autowired
    private ReceiveNodeRepository receiveNodeRepository;

    @Autowired
    private ProjectRepository projectRepository;

    @Override
    public Long save(TaxEntity taxEntity) {
        ReceiveNodeEntity receiveNodeEntity = receiveNodeRepository.buildReceiveNodeEntity(taxEntity.getReceiveNodeId());
        TaxPo taxPo = convertToTaxPo(taxEntity,receiveNodeEntity);
        dao.save(taxPo);
        taxEntity.setId(taxPo.getId());
        receiveNodeRepository.addTax(receiveNodeEntity, taxEntity);
        return taxPo.getId();
    }

    @Override
    public void updateCaseChangeReceiveNode(TaxEntity taxEntity) {
        Long taxId = taxEntity.getId();
        TaxEntity oldTaxEntity = buildTaxEntity(taxId);
        if(taxEntity.hasChangeReceiveNode(oldTaxEntity.getReceiveNodeId())){
            taxEntity.init(oldTaxEntity);
            //删除原来的节点与开票的依赖
            ReceiveRecordDaoQuery receiveRecordDaoQuery = new ReceiveRecordDaoQuery();
            receiveRecordDaoQuery.setTaxId(taxId);
            List<ReceiveRecordPo> receiveRecordPoList =  receiveRecordDao.selectByQuery(receiveRecordDaoQuery);
            if(CollectionUtils.isNotEmpty(receiveRecordPoList)){
                for(ReceiveRecordPo receiveRecordPo : receiveRecordPoList){
                    receiveRecordDao.removeById(receiveRecordPo.getId());
                    ReceiveRecordEntity receiveRecordEntity = buildReceiveRecordEntity(receiveRecordPo);
                    delRecord(buildTaxEntity(taxId),receiveRecordEntity);
                }
            }
            del(taxId);
            //添加新的依赖
            save(taxEntity);
            if(CollectionUtils.isNotEmpty(receiveRecordPoList)){
                for(ReceiveRecordPo receiveRecordPo : receiveRecordPoList){
                    receiveRecordPo.setReceiveNodeId(taxEntity.getReceiveNodeId());
                    receiveRecordPo.setTaxId(taxId);
                    receiveRecordDao.save(receiveRecordPo);
                    addRecord(buildTaxEntity(taxEntity.getId()),buildReceiveRecordEntity(receiveRecordPo));
                }
                projectRepository.updateReceiveCycle(oldTaxEntity.getProjectId());
            }
        }else {
            update(taxEntity,oldTaxEntity);
        }
    }

    @Override
    public void update(TaxEntity taxEntity) {
        Long taxId = taxEntity.getId();
        TaxEntity oldTaxEntity = buildTaxEntity(taxId);
        update(taxEntity, oldTaxEntity);
    }

    @Override
    public void del(Long id) {
        TaxEntity taxEntity = buildEntity(dao.getById(id));
        ReceiveRecordDaoQuery receiveRecordDaoQuery = new ReceiveRecordDaoQuery();
        receiveRecordDaoQuery.setTaxId(id);
        List<ReceiveRecordPo> receiveRecordPoList =  receiveRecordDao.selectByQuery(receiveRecordDaoQuery);
        if(CollectionUtils.isEmpty(receiveRecordPoList)){
            dao.removeById(id);
        }else{
            throw new ArmException(ErrorEnum.VAILD_ERROR,"该开票下存在收款记录,不可删除");
        }
        ReceiveNodeEntity receiveNodeEntity = receiveNodeRepository.buildReceiveNodeEntity(taxEntity.getReceiveNodeId());
        receiveNodeRepository.delTax(receiveNodeEntity,taxEntity);
    }

    @Override
    public void addRecord(TaxEntity taxEntity, ReceiveRecordEntity receiveRecordEntity) {
        taxEntity.addRecord(receiveRecordEntity);
        update(taxEntity);
    }

    @Override
    public void updateRecord(TaxEntity taxEntity, ReceiveRecordEntity oldReceiveRecordEntity, ReceiveRecordEntity newReceiveRecordEntity) {
        taxEntity.updateRecord(oldReceiveRecordEntity,newReceiveRecordEntity);
        update(taxEntity);
    }

    @Override
    public void delRecord(TaxEntity taxEntity, ReceiveRecordEntity receiveRecordEntity) {
        taxEntity.delRecord(receiveRecordEntity);
        update(taxEntity);
    }

    private void update(TaxEntity taxEntity, TaxEntity oldTaxEntity) {
        ReceiveNodeEntity receiveNodeEntity = receiveNodeRepository.buildReceiveNodeEntity(oldTaxEntity.getReceiveNodeId());
        dao.updateById(convertToTaxPo(taxEntity,receiveNodeEntity));
        receiveNodeRepository.updateTax(receiveNodeEntity,oldTaxEntity,taxEntity);
    }

    private TaxPo convertToTaxPo(TaxEntity entity,ReceiveNodeEntity receiveNodeEntity) {
        TaxPo taxPo = convertToTaxPo(entity);
        if (taxPo.getProjectId() == null) {
            taxPo.setProjectId(receiveNodeEntity.getProjectId());
        }
        return taxPo;
    }

    private TaxPo convertToTaxPo(TaxEntity entity) {
        TaxPo taxPo = new TaxPo();
        BeanUtils.copyProperties(entity, taxPo);
        return taxPo;
    }

    public TaxEntity buildTaxEntity(Long id) {
        TaxPo po = dao.getById(id);
        return buildEntity(po);
    }

    private TaxEntity buildEntity(TaxPo po) {
        TaxEntity entity = new TaxEntity();
        BeanUtils.copyProperties(po, entity);
        return entity;
    }

    private ReceiveRecordEntity buildReceiveRecordEntity(ReceiveRecordPo po){
        ReceiveRecordEntity receiveRecordEntity = new ReceiveRecordEntity();
        BeanUtils.copyProperties(po,receiveRecordEntity);
        return receiveRecordEntity;
    }

}
